package org.elastic.compreplatform.common.util;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ClassName: ZipUtil 
 * @Description: ZIP压缩工具
 * @author JornTang
 * @date 2018年2月7日
 */
public class ZipUtil{
	private static Logger log = LoggerFactory.getLogger(ZipUtil.class);
	public static String CHARSET = "UTF-8";

	/**
	 * @param src 源文件(或目录)
	 * @param out 输出流
	 * @throws IOException
	 */
	public static void zip(File src, OutputStream out) throws IOException{
		ZipOutputStream zos = null;
		try{
			zos = new ZipOutputStream(out);
			zipZos(src,zos);
		}finally{
			closeQuiet(zos);
		}
	}
	private static void zipZos(File src, ZipOutputStream zos) throws IOException{
		if(src.isDirectory()){
			for(File entry : src.listFiles()) {
				zipIteration(zos, entry, "");
			}
		}else {
			zipIteration(zos, src, "");
		}
	}
	/**
	 * 递归压缩文件或目录
	 * @param out 压缩输出流对象
	 * @param file 当前待压缩文件
	 * @param curPath 当前位置路径
	 */
	private static void zipIteration(ZipOutputStream out, File file, String curPath) throws IOException{
		out.setEncoding(CHARSET);
		FileInputStream in = null;
		try{
			if(file.isDirectory()){
				File[] entries = file.listFiles();
				if(entries.length == 0){
					out.putNextEntry(new ZipEntry(curPath + file.getName() + "/"));
					out.closeEntry();
				}else{
					for(File entry : entries){
						zipIteration(out, entry, curPath + file.getName() + "/");
					}
				}
			}else{
				ZipEntry entry = new ZipEntry(curPath + file.getName());
				out.putNextEntry(entry);

				in = new FileInputStream(file);
				io(in, out, 4 * 1024);

				out.closeEntry();
			}
		}finally{
			closeQuiet(in);
		}
	}
	private static void closeQuiet(Closeable c) {
		if (c != null)
			try {
				c.close();
			} catch (IOException e) {
			}
	}
	private static int io(InputStream i, OutputStream o, int bufferSize)
			throws IOException {
		byte[] buffer = new byte[bufferSize];
		int read, total = 0;
		while ((read = i.read(buffer)) != -1) {
			total += read;
			o.write(buffer, 0, read);
		}
		return total;
	}
}
